// 
//  Copyright (C) 2009 Jacek Trubłajewicz
// 
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// 

using System;
using System.Drawing;
using HAKGERSoft;
using Mono.Unix;
using NLog;

namespace wxGadu
{
	
	
	public class ConfigurationDialog : wx.Dialog
	{		
		#region Id
		public enum Id
		{
			configNotebook,
			gaduPanel,
			appearancePanel,
			behaviourPanel,
			statusPanel,
			defaultButton
		}
		#endregion
		
		#region controls
		private wx.Notebook configNotebook;
		private GaduSettingsPanel gaduPanel;
		private AppearanceSettingsPanel appearancePanel;
		private BehaviourSettingsPanel behaviourPanel;
		private StatusTrackingPanel statusPanel;
		private wx.Button okButton;
		private wx.Button cancelButton;
		private wx.Button defaultButton;
		#endregion
		
		#region data members
		private AppConfig appConf;
		private UserConfig userConf;
		private UserConfig userConfBackup;
		private bool useBackupConf;
#if LOG
		private Logger logger = LogManager.GetCurrentClassLogger();	
#endif
		private MainFrame mainFrame;
		#endregion

		
		public ConfigurationDialog(wx.Window parent, int id, string title, Point pos, Size size, uint style):
			base(parent, id, title, pos, size, style)
		{
			mainFrame = (MainFrame) parent;
			appConf = mainFrame.AppCfg;
			userConf = mainFrame.AppCfg.UserConf;
			DoControls();
			DoLayout();
			
			EVT_BUTTON((int) Id.defaultButton, new wx.EventListener(OnDefaultButtonClicked));
			EVT_BUTTON(wx.Window.wxID_CANCEL, new wx.EventListener(OnCancelButton));
						
			this.Size = new Size(505, 535);
		}
		
		private void DoControls()
		{
			configNotebook = new wx.Notebook(this, (int) Id.configNotebook, 
			                                wx.Window.wxDefaultPosition, wx.Window.wxDefaultSize);                           
			wx.ImageList images = new wx.ImageList();
			images.Add(mainFrame.ImageMgr[ImageManager.GADU_SETTINGS]);
			images.Add(mainFrame.ImageMgr[ImageManager.APPEARANCE_SETTINGS]);
			images.Add(mainFrame.ImageMgr[ImageManager.BEHAVIOUR_SETTINGS]);
			images.Add(mainFrame.ImageMgr[ImageManager.STATUS_TRACKING]);
			configNotebook.Images = images;

			gaduPanel = new GaduSettingsPanel(configNotebook, (int) Id.gaduPanel, wx.Window.wxDefaultPosition,
			                                  wx.Window.wxDefaultSize, wx.Window.wxTAB_TRAVERSAL);
			appearancePanel = new AppearanceSettingsPanel(configNotebook, (int) Id.appearancePanel, wx.Window.wxDefaultPosition,
			                                  wx.Window.wxDefaultSize, wx.Window.wxTAB_TRAVERSAL);
			behaviourPanel = new BehaviourSettingsPanel(configNotebook, (int) Id.behaviourPanel, wx.Window.wxDefaultPosition,
			                                  wx.Window.wxDefaultSize, wx.Window.wxTAB_TRAVERSAL);
			statusPanel = new StatusTrackingPanel(configNotebook, (int) Id.statusPanel, 
			                                      wx.Window.wxDefaultPosition, wx.Window.wxDefaultSize,
			                                      wx.Window.wxTAB_TRAVERSAL, mainFrame.Dispatch.ContactMgr);
			
			configNotebook.AddPage(gaduPanel, Catalog.GetString("Gadu-Gadu"), true, 0);
			configNotebook.AddPage(appearancePanel, Catalog.GetString("Appearance"), false, 1);
			configNotebook.AddPage(behaviourPanel, Catalog.GetString("Behaviour"), false, 2);
			configNotebook.AddPage(statusPanel, Catalog.GetString("Status change tracking"), false, 3);
			
			okButton = new wx.Button(this, wx.Window.wxID_OK, Catalog.GetString("OK"));
			cancelButton = new wx.Button(this, wx.Window.wxID_CANCEL, Catalog.GetString("Cancel"));
			defaultButton = new wx.Button(this, (int) Id.defaultButton, Catalog.GetString("Default"));
		}
		
		private void DoLayout()
		{
			wx.BoxSizer topSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
			{
				wx.BoxSizer boxSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
				{
					boxSizer.Add(configNotebook, 1, wx.Stretch.wxEXPAND);
					
					wx.BoxSizer buttonSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
					{
						buttonSizer.Add(20, 20 , 1, 0, 0);
						buttonSizer.Add(okButton, 0, wx.Direction.wxRIGHT, 5);
						buttonSizer.Add(defaultButton, 0, wx.Direction.wxRIGHT, 5);
						buttonSizer.Add(cancelButton, 0, 0, 0);
					}
					boxSizer.Add(buttonSizer, 0, wx.Stretch.wxEXPAND|wx.Direction.wxTOP, 10);
				}
				topSizer.Add(boxSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
			}
			this.Sizer = topSizer;
			topSizer.Fit(this);
			topSizer.SetSizeHints(this);
		}
		
		private void OnDefaultButtonClicked(object sender, wx.Event evt)
		{
			// TODO: even if user click next cancel 
			// default values will be active 
			userConf.SetDefaultValues();
			LoadControlsState();
		}
		
		private void LoadControlsState()
		{
			gaduPanel.Uin = userConf.Uin;
//			gaduPanel.Password = appConf.Password;
			gaduPanel.Name = userConf.Name;
			
			switch (userConf.DefaultStatus)
			{
				case GGStatusType.Available: 
					gaduPanel.DefaultStatusSelection = 0;
				 break;
				case GGStatusType.Busy:
					gaduPanel.DefaultStatusSelection = 1;
				 break;
				case GGStatusType.Invisible:
					gaduPanel.DefaultStatusSelection = 2;
				 break;
				case GGStatusType.NotAvailable:
					gaduPanel.DefaultStatusSelection = 3;
				 break;			
				default: 
#if LOG
					logger.Warn(Catalog.GetString("Invalid value of default user status"));
#endif
					gaduPanel.DefaultStatusSelection = 3;
				break;
			}
			
			gaduPanel.SaveDescriptionsCheck = userConf.SaveDescription;
			gaduPanel.AutoSelectServerCheck = userConf.AutomaticGaduServer;
			gaduPanel.GGServerAddress = userConf.GaduServerAddress;
			gaduPanel.ConnectionTimeout = userConf.ConnectionTimeout;
			
			#region setting colors
			if (userConf.ContactListBackground is Colour)
			{
				appearancePanel.ContactListBgCheck = false;
				appearancePanel.ContactListBgTC = (wx.Colour) userConf.ContactListBackground;
				appearancePanel.ContactListBgColor = userConf.ContactListBackground;
			}
			else
			{
				appearancePanel.ContactListBgCheck = true;
				appearancePanel.ContactListBgColor = null;
			}
			
			if (userConf.InfoPanelBackground is Colour)
			{
				appearancePanel.InfoPanelBgCheck = false;
				appearancePanel.InfoPanelBgTC = (wx.Colour) userConf.InfoPanelBackground;
				appearancePanel.InfoPanelBgColor = userConf.InfoPanelBackground;
			}
			else
			{
				appearancePanel.InfoPanelBgCheck = true;
				appearancePanel.InfoPanelBgColor = null;
			}
			#endregion
			
			#region setting fonts
			if (userConf.ContactListFont is wxGadu.Font)
			{
				appearancePanel.ContactListFontCheck = false;
				appearancePanel.ContactListFontTC = userConf.ContactListFont.FaceName + ' ' + 
					userConf.ContactListFont.Family.ToString() + 
					userConf.ContactListFont.Size;
				appearancePanel.ContactListFont = userConf.ContactListFont;
			}
			else
			{
				appearancePanel.ContactListFontCheck = true;
				appearancePanel.ContactListFont = null;
			}
			
			if (userConf.InfoPanelFont is wxGadu.Font)
			{
				appearancePanel.InfoPanelFontCheck = false;
				appearancePanel.InfoPanelFontTC = userConf.InfoPanelFont.FaceName + ' ' + 
					userConf.InfoPanelFont.Family.ToString() + 
					userConf.InfoPanelFont.Size;
				appearancePanel.InfoPanelFont = userConf.InfoPanelFont;
			}
			else
			{
				appearancePanel.InfoPanelFontCheck = true;
				appearancePanel.InfoPanelFont = null;
			}
			
			if (userConf.TopChatWindowFont is wxGadu.Font)
			{
				appearancePanel.TopChatFontCheck = false;
				appearancePanel.TopChatFontTC = userConf.TopChatWindowFont.FaceName + ' ' + 
					userConf.TopChatWindowFont.Family.ToString() + 
					userConf.TopChatWindowFont.Size;
				appearancePanel.TopChatFont = userConf.TopChatWindowFont;
			}
			else
			{
				appearancePanel.TopChatFontCheck = true;
				appearancePanel.TopChatFont = null;
			}
			
			if (userConf.BottomChatWindowFont is wxGadu.Font)
			{
				appearancePanel.ChatEntryFontCheck = false;
				appearancePanel.ChatEntryFontTC = userConf.BottomChatWindowFont.FaceName + ' ' + 
					userConf.BottomChatWindowFont.Family.ToString() + 
					userConf.BottomChatWindowFont.Size;
				appearancePanel.ChatEntryFont = userConf.BottomChatWindowFont;
			}
			else
			{
				appearancePanel.ChatEntryFontCheck = true;
				appearancePanel.ChatEntryFont = null;
			}
			#endregion
			
			appearancePanel.MainWindowWidth = userConf.MainWindowSize.Width;
			appearancePanel.MainWindowHeight = userConf.MainWindowSize.Height;
			appearancePanel.ChatWindowWidth = userConf.ChatWindowSize.Width;
			appearancePanel.ChatWindowHeight = userConf.ChatWindowSize.Height;
			
			#region setting logging levels
			behaviourPanel.FileLoggingComboSelection = (int) userConf.FileLoggingLevel;
			behaviourPanel.ConsoleLoggingComboSelection = (int) userConf.ConsoleLoggingLevel;
			#endregion
			
			behaviourPanel.MainWindowXPositon = userConf.MainWindowPosition.X;
			behaviourPanel.MainWindowYPositon = userConf.MainWindowPosition.Y;
			behaviourPanel.ChatWindowXPositon = userConf.ChatWindowPosition.X;
			behaviourPanel.ChatWindowYPositon = userConf.ChatWindowPosition.Y;
			
			behaviourPanel.EnterSend = userConf.EnterSend;
			behaviourPanel.EnableTrayIcon = userConf.EnableTrayIcon;
			behaviourPanel.ConfirmExit = userConf.ConfirmExit;
			behaviourPanel.ShowTooltips = userConf.ShowTooltips;
			behaviourPanel.TooltipsDelay = userConf.TooltipsDelay;
			behaviourPanel.ShowNewChatNotify = userConf.ShowNewChatNotify;
			behaviourPanel.NotifyTtl = userConf.NotifyTtl;
			behaviourPanel.CloseToTray = userConf.CloseToTray;
			behaviourPanel.ChatMessageCount = userConf.ChatWindowMessagesCount;
			behaviourPanel.SaveHistory = userConf.SaveHistory;
			
			statusPanel.EnableStatusChangeNotify = userConf.EnableContactStatusNotify;
			statusPanel.ShowOnlyAvailableNotify = userConf.ShowOnlyAvailableNotify;
			statusPanel.TrackedList = userConf.TrackedContacts;
		}
		
		public override bool TransferDataToWindow()
		{
			// load user conf from file only if is not loaded, which should not happen
			// we do that to avoid losing changes that are in memory but haven't been 
			// saved to config file
			if (userConf == null) 
			{
#if LOG
				logger.Warn(Catalog.GetString("User configuration settings object is null, that should not happen"));
#endif
				try
	 			{
	 				userConf = appConf.LoadUserConfig();
	 			}
	 			catch (Exception e)
	 			{
	 				wx.MessageDialog md = new wx.MessageDialog(this, 
	 				                                           string.Format(
	 			                                                         Catalog.GetString("Unable to load configuration file: {0}\n{1}\n\nLoading default settings"), appConf.ConfigFile, e.Message),
	 				                                                         Catalog.GetString("Error"),
	 			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
	 				md.ShowModal();    
#if LOG
	 				logger.Warn(string.Format(Catalog.GetString("Unable to load configuration file: {0}. Loading default settings..."), appConf.ConfigFile));
#endif
	 				userConf = new UserConfig();
	 			}
			}
 			
 			LoadControlsState();
			// create a copy of config which will be used when
			// user choose default a then cancel saving settings
			userConfBackup = (UserConfig) userConf.Clone(); 	
			
 			return true;
 		}
		
		public override bool TransferDataFromWindow()
		{
			wx.MessageDialog md;
			
			if (gaduPanel.Uin.Trim() == string.Empty || gaduPanel.Name.Trim() == string.Empty/* || gaduPanel.Password.Trim() == string.Empty*/)
			{
				md = new wx.MessageDialog(this, 
				                                           string.Format(
				                                                         Catalog.GetString("GG number and Name fields cannot be empty")),
				                                                         Catalog.GetString("Invalid value"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
				md.ShowModal(); 
				
				return false;
			}
			
			int res;
			if (!Int32.TryParse(gaduPanel.Uin.Trim(), out res))
			{
				md = new wx.MessageDialog(this, 
				                                           string.Format(
				                                                         Catalog.GetString("UIN field must contain only numeric characters")),
				                                                         Catalog.GetString("Invalid value"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
				md.ShowModal(); 
				
				return false;
			}
			
			userConf.Uin = gaduPanel.Uin.Trim();
			
//			if (!(appConf.Password ==  gaduPanel.Password.Trim()))
//			{
//				md = new wx.MessageDialog(this, 
//				                                           string.Format(
//				                                                         Catalog.GetString("Your GG password has changed, notice that this will NOT automatic change your GG account password on GG server.")),
//				                                                         Catalog.GetString("Password"),
//			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_ASTERISK);
//				md.ShowModal(); 
//				appConf.Password = gaduPanel.Password.Trim();
//			}
			userConf.Name = gaduPanel.Name.Trim();
			
			switch (gaduPanel.DefaultStatusSelection)
			{
				case 0:
					userConf.DefaultStatus = GGStatusType.Available;
					break;
				case 1:
					userConf.DefaultStatus = GGStatusType.Busy;
					break;
				case 2:
					userConf.DefaultStatus = GGStatusType.Invisible;
					break;
				case 3:
					userConf.DefaultStatus = GGStatusType.NotAvailable;
					break;
				default:
					userConf.DefaultStatus = GGStatusType.NotAvailable;
					break;
			}
			
			userConf.SaveDescription = gaduPanel.SaveDescriptionsCheck;
			if (gaduPanel.AutoSelectServerCheck == false && gaduPanel.GGServerAddress.Trim() != string.Empty)
			{
				userConf.AutomaticGaduServer = gaduPanel.AutoSelectServerCheck;
				userConf.GaduServerAddress = gaduPanel.GGServerAddress;
			}
			else
				userConf.AutomaticGaduServer = true;
			
			userConf.ConnectionTimeout = gaduPanel.ConnectionTimeout;
			
			#region colors
			if (appearancePanel.ContactListBgCheck)
				userConf.ContactListBackground = null;
			else
				userConf.ContactListBackground = appearancePanel.ContactListBgColor;
			
			if (appearancePanel.InfoPanelBgCheck)
				userConf.InfoPanelBackground = null;
			else
				userConf.InfoPanelBackground = appearancePanel.InfoPanelBgColor;
			#endregion
			
			#region fonts
			if (appearancePanel.ContactListFontCheck)
				userConf.ContactListFont = null;
			else
				userConf.ContactListFont = appearancePanel.ContactListFont;
			
			if (appearancePanel.InfoPanelFontCheck)
				userConf.InfoPanelFont = null;
			else
				userConf.InfoPanelFont = appearancePanel.InfoPanelFont;
			
			if (appearancePanel.TopChatFontCheck)
				userConf.TopChatWindowFont = null;
			else
				userConf.TopChatWindowFont = appearancePanel.TopChatFont;
			
			if (appearancePanel.ChatEntryFontCheck)
				userConf.BottomChatWindowFont = null;
			else
				userConf.BottomChatWindowFont = appearancePanel.ChatEntryFont;
			#endregion
			
			userConf.MainWindowSize = new Size(appearancePanel.MainWindowWidth, appearancePanel.MainWindowHeight);
			userConf.ChatWindowSize = new Size(appearancePanel.ChatWindowWidth, appearancePanel.ChatWindowHeight);
			
			userConf.FileLoggingLevel = (LogLevel) behaviourPanel.FileLoggingComboSelection;
			userConf.ConsoleLoggingLevel = (LogLevel) behaviourPanel.ConsoleLoggingComboSelection;
			
			userConf.MainWindowPosition = new Point(behaviourPanel.MainWindowXPositon, behaviourPanel.MainWindowYPositon);
			userConf.ChatWindowPosition = new Point(behaviourPanel.ChatWindowXPositon, behaviourPanel.ChatWindowYPositon);
			
			userConf.EnterSend = behaviourPanel.EnterSend;
			userConf.EnableTrayIcon = behaviourPanel.EnableTrayIcon;
			userConf.ConfirmExit = behaviourPanel.ConfirmExit;
			userConf.ShowTooltips = behaviourPanel.ShowTooltips;
			userConf.TooltipsDelay = behaviourPanel.TooltipsDelay;
			userConf.ShowNewChatNotify = behaviourPanel.ShowNewChatNotify;
			userConf.NotifyTtl = behaviourPanel.NotifyTtl;
			userConf.CloseToTray = behaviourPanel.CloseToTray;
			userConf.ChatWindowMessagesCount = behaviourPanel.ChatMessageCount;
			userConf.SaveHistory = behaviourPanel.SaveHistory;
			
			userConf.EnableContactStatusNotify = statusPanel.EnableStatusChangeNotify;
			userConf.ShowOnlyAvailableNotify = statusPanel.ShowOnlyAvailableNotify;
			userConf.TrackedContacts = statusPanel.TrackedList;
			
			try 
			{
				appConf.SaveUserConfig();
			}
			catch (Exception e)
			{
#if LOG
				logger.Error(String.Format(Catalog.GetString("Unable to save user configuration settings into: {0}. {1}"), appConf.ConfigFile, e.Message));
#endif
				md = new wx.MessageDialog(this, 
				                                           string.Format(
				                                                         Catalog.GetString("Unable to save user configuration settings to: {0}.\n{1}"), appConf.ConfigFile, e.Message),
				                                                         Catalog.GetString("Error"),
			                                           wx.MessageDialog.wxOK|wx.MessageDialog.wxICON_EXCLAMATION);
				md.ShowModal(); 
			}
				
			appConf.ApplyUserSettings();	
			
			return true;
		}
		
		private void OnCancelButton(object sender, wx.Event evt)
		{
#if LOG
			logger.Trace(Catalog.GetString("Restoring previous user configuration"));
#endif
			mainFrame.AppCfg.UserConf = userConfBackup;
			evt.Skip();
		}
	}
}
